home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / hypercar / xfcn / spttool.cpt / Support Tools eXternals 1.2.5 / card_32474.txt < prev    next >
Text File  |  1990-11-13  |  17KB  |  488 lines

  1. -- card: 32474 from stack: in.5
  2. -- bmap block id: 42372
  3. -- flags: 0000
  4. -- background id: 3858
  5. -- name: DragRect
  6. ----- HyperTalk script -----
  7. on OpenCard
  8.   global INITIAL_LOC
  9.   put the loc of cd btn 1 into line 1 of INITIAL_LOC
  10.   put the loc of cd btn 2 into line 2 of INITIAL_LOC
  11.   pass OpenCard
  12. end OpenCard
  13.  
  14. on CloseCard
  15.   global INITIAL_LOC
  16.   set the loc of cd btn 1 to line 1 of INITIAL_LOC
  17.   set the loc of cd btn 2 to line 2 of INITIAL_LOC
  18.   pass CloseCard
  19. end CloseCard
  20.  
  21. on hideObjects
  22.   hide cd btn 1
  23.   hide cd btn 2
  24.   hide cd fld "label"
  25. end hideObjects
  26.  
  27. on showObjects
  28.   show cd btn 1
  29.   show cd btn 2
  30.   show cd fld "label"
  31. end showObjects
  32.  
  33.  
  34. -- part 2 (field)
  35. -- low flags: 01
  36. -- high flags: 0000
  37. -- rect: left=28 top=171 right=207 bottom=212
  38. -- title width / last selected line: 0
  39. -- icon id / first selected line: 0 / 0
  40. -- text alignment: 1
  41. -- font id: 3
  42. -- text size: 12
  43. -- style flags: 0
  44. -- line height: 16
  45. -- part name: label
  46.  
  47.  
  48. -- part 3 (button)
  49. -- low flags: 00
  50. -- high flags: 8004
  51. -- rect: left=22 top=279 right=310 bottom=210
  52. -- title width / last selected line: 0
  53. -- icon id / first selected line: 0 / 0
  54. -- text alignment: 1
  55. -- font id: 3
  56. -- text size: 10
  57. -- style flags: 0
  58. -- line height: 13
  59. -- part name: DragRect(rect of me, "NoClipping")
  60. ----- HyperTalk script -----
  61. on mouseDown
  62.   put the rect of me into buttonRect
  63.   put the loc of me into myLoc
  64.   put DragRect(the rect of me, "noclipping") into locOffset
  65.   --
  66.   -- convert HC window location to local coords
  67.   put the rect of cd window into windowRect
  68.   put OffsetRect(-(item 1 of windowRect), -(item 2 of windowRect), windowRect) into windowRect
  69.   --
  70.   -- what will the rect of the button be now?
  71.   put OffsetRect(item 1 of locOffset, item 2 of locOffset, buttonRect) into buttonRect
  72.   --
  73.   --  make a slightly smaller than actual size rect (small safety
  74.   --   margin) for the new button so that we can test to see if it
  75.   --   will end up off-screen if we move it
  76.   put item 1 of buttonRect + 5 & "," & item 2 of buttonRect + 5 into topLeft
  77.   put item 3 of buttonRect - 5 & "," & item 4 of buttonRect - 5 into botRight
  78.   put item 3 of buttonRect - 5 & "," & item 2 of buttonRect + 5 into topRight
  79.   put item 1 of buttonRect + 5 & "," & item 4 of buttonRect - 5 into botLeft
  80.   --
  81.   -- see if the button was released offscreen
  82.   if (topLeft is not within windowRect) and (botRight is not within windowRect) and (topRight is not within windowRect) and (botLeft is not within windowRect) then
  83.     answer "This button can't be moved outside of HC's window."
  84.   else
  85.     add item 1 of locOffset to item 1 of myLoc
  86.     add item 2 of locOffset to item 2 of myLoc
  87.     set the loc of me to myLoc
  88.   end if
  89. end mouseDown
  90.  
  91. function OffsetRect deltaX, deltaY, origRect
  92. -- offset a rectangle, useful for converting between local (within
  93. --  HC's card window) and global coordinates
  94. add deltaX to item 1 of origRect
  95. add deltaX to item 3 of origRect
  96. add deltaY to item 2 of origRect
  97. add deltaY to item 4 of origRect
  98. return origRect
  99. end OffsetRect
  100.  
  101.  
  102.  
  103. -- part 4 (button)
  104. -- low flags: 00
  105. -- high flags: 8004
  106. -- rect: left=44 top=223 right=254 bottom=183
  107. -- title width / last selected line: 0
  108. -- icon id / first selected line: 0 / 0
  109. -- text alignment: 1
  110. -- font id: 3
  111. -- text size: 10
  112. -- style flags: 0
  113. -- line height: 13
  114. -- part name: DragRect(rect of me)
  115. ----- HyperTalk script -----
  116. on mouseDown
  117.   put the rect of me into buttonRect
  118.   put the loc of me into myLoc
  119.   put DragRect(rect of me) into locOffset
  120.   --
  121.   -- convert HC window location to local coords
  122.   put the rect of cd window into windowRect
  123.   put OffsetRect(-(item 1 of windowRect), -(item 2 of windowRect), windowRect) into windowRect
  124.   --
  125.   -- what will the rect of the button be now?
  126.   put OffsetRect(item 1 of locOffset, item 2 of locOffset, buttonRect) into buttonRect
  127.   --
  128.   --  make a slightly smaller than actual size rect (small safety
  129.   --   margin) for the new button so that we can test to see if it
  130.   --   will end up off-screen if we move it
  131.   put item 1 of buttonRect + 5 & "," & item 2 of buttonRect + 5 into topLeft
  132.   put item 3 of buttonRect - 5 & "," & item 4 of buttonRect - 5 into botRight
  133.   put item 3 of buttonRect - 5 & "," & item 2 of buttonRect + 5 into topRight
  134.   put item 1 of buttonRect + 5 & "," & item 4 of buttonRect - 5 into botLeft
  135.   --
  136.   -- see if the button was released offscreen
  137.   if (topLeft is not within windowRect) and (botRight is not within windowRect) and (topRight is not within windowRect) and (botLeft is not within windowRect) then
  138.     answer "The button can't be moved outside of HC's window."
  139.   else
  140.     add item 1 of locOffset to item 1 of myLoc
  141.     add item 2 of locOffset to item 2 of myLoc
  142.     set the loc of me to myLoc
  143.   end if
  144. end mouseDown
  145.  
  146. function OffsetRect deltaX, deltaY, origRect
  147. -- offset a rectangle, useful for converting between local (within
  148. --  HC's card window) and global coordinates
  149. add deltaX to item 1 of origRect
  150. add deltaX to item 3 of origRect
  151. add deltaY to item 2 of origRect
  152. add deltaY to item 4 of origRect
  153. return origRect
  154. end OffsetRect
  155.  
  156.  
  157.  
  158. -- part contents for background part 38
  159. ----- text -----
  160. 12/50
  161.  
  162. -- part contents for card part 2
  163. ----- text -----
  164. Drag the button below to see an example of DragRect
  165.  
  166. -- part contents for background part 20
  167. ----- text -----
  168.      An XFCN which drags a gray rectangle around the screen as the mouse is moved.  The XFCN returns the distance between the original rectangle (the XFCN's parameter) and the final rectangle (the point at which the mouse button was released).  The XFCN keeps control until the mouse button is released.
  169.      If the optional second parameter contains the literal string ΓÇ£NOCLIPPINGΓÇ¥  the rect can be dragged anywhere on the screen, otherwise the rect can not be dragged outside of the rect of the card window.  Look at the buttons on the right for examples.
  170.  
  171. Calling syntax : DragRect(objectRect, <ΓÇ£NOCLIPPINGΓÇ¥>)
  172. OBJECTRECT : the coordinates of the rectangle to be dragged.
  173. NOCLIPPING :  do not limit dragging to withing the card window (optional)
  174.  
  175.  
  176. -- part contents for background part 42
  177. ----- text -----
  178. unit DragRect;
  179. {drag a gray rectangle around the screen, retun the offset from it's start point.  constrain the dragging to }
  180. { the area of the card window unless otherwise requested, in which case we limit dragging to the desktop }
  181. {}
  182. {   brought to you by:    Anup Murarka           Eric Carlson          }
  183. {                       ALINK:  SKEPTIC           ALINK:  cyNic   }
  184. {                                   CIS:  76004,3356        }
  185. {}
  186. {               We are part of the Support Tools Development Group,    }
  187. {               Apple Computer, Inc.     }
  188. {}
  189. {               please DO NOT contack Mac DTS for support of this code!   }
  190. {}
  191. {               please DO contact the authors for support of this code!  }
  192. {}
  193. {               Send comments, bug reports, requests to any of the above    }
  194. {               E-mail addresses or to:}
  195. {}
  196. {                           (one of us)                    }
  197. {                           Apple Computer, Inc.         }
  198. {                           900 E. Hamilton, Ave.       }
  199. {                           Campbell, CA   95008       }
  200. {                           M/S 72-L                     }
  201. {}
  202. {   Copyright:    ┬⌐ 1989, 1990 by Apple Computer, Inc., all rights reserved.     }
  203. {}
  204. { written by Eric Carlson                                      }
  205. { AppleLink:  cyNic                                                }
  206. { modification history                                           }
  207. {          Date          Initials                                      Comments                                     }
  208. {          ----          ------      -----------------------------------------------------    }
  209. {       8/26/89          ec            first written                                                                     }
  210. {       5/13/90          ec            version 1.1,  modified to allow dragging outside of HC's widow }
  211. {}
  212.  
  213. interface
  214.  uses
  215.   HyperXCmd;
  216.  
  217.  procedure main (paramPtr: XCmdPtr);
  218.  
  219. implementation
  220.  
  221.  function AskedForHelp (paramPtr: XCmdPtr;
  222.        syntaxMsg: Str255;
  223.        copyrightMsg: Str255): boolean;
  224. {check to see if the user sent a '?' or a '!' as }
  225. { the only parameter. if so we will respond with }
  226. { the calling syntax or the copyright/version info }
  227. { for this external }
  228. {}
  229.   var
  230.    firstStr: str255;
  231.  begin
  232.   askedForHelp := false;
  233.   if paramPtr^.paramCount = 1 then
  234.    begin
  235.     ZeroToPas(paramPtr, paramPtr^.params[1]^, firstStr);
  236. { what is the first param? }
  237.     if firstStr = '?' then
  238.      begin
  239.       paramPtr^.returnValue := PasToZero(paramPtr, syntaxMsg);
  240.       askedForHelp := true
  241.      end{ asked for help }
  242.     else if firstStr = '!' then
  243.      begin
  244.       paramPtr^.returnValue := PasToZero(paramPtr, copyRightMsg);
  245.       askedForHelp := true
  246.      end;{ asked for copyright info }
  247.    end;{ one parameter passed }
  248.  end;{ function }
  249.  
  250.  function NumberToString (paramPtr: XCmdPtr;
  251.        num: LONGINT): Str255;
  252. { use the toolbox call rather than HC's, implement it as a function }
  253.   var
  254.    tempStr: str255;
  255.  begin
  256.   NumToString(num, tempStr);
  257.   NumberToString := tempStr;
  258.  end;
  259.  
  260.  function rectToStr (paramPtr: XCMDPtr;
  261.        r: Rect): Str255;
  262. { convert a rect to a string so that it can be used in callbacks or as the result of an external }
  263.   var
  264.    tempStr: Str255;
  265.  begin
  266.   with r do
  267.    begin
  268.     tempStr := CONCAT(NumberToString(paramPtr, left), ',');
  269.     tempStr := CONCAT(tempStr, NumberToString(paramPtr, top), ',');
  270.     tempStr := CONCAT(tempStr, NumberToString(paramPtr, right), ',');
  271.     tempStr := CONCAT(tempStr, NumberToString(paramPtr, bottom));
  272.    end;
  273.   rectToStr := tempStr;
  274.  end;
  275.  
  276.  function strToRect (paramPtr: XCMDPtr;
  277.        rectStr: Str255): Rect;
  278. { convert a string, as from a callback or a passed parameter, to a rect }
  279.   var
  280.    where: Integer;
  281.    tempRect: rect;
  282.  begin
  283.   where := POS(',', rectStr);
  284.   tempRect.left := StrToNum(paramPtr, COPY(rectStr, 1, where - 1));
  285.   DELETE(rectStr, 1, where);
  286.  
  287.   where := POS(',', rectStr);
  288.   tempRect.top := StrToNum(paramPtr, COPY(rectStr, 1, where - 1));
  289.   DELETE(rectStr, 1, where);
  290.  
  291.   where := POS(',', rectStr);
  292.   tempRect.right := StrToNum(paramPtr, COPY(rectStr, 1, where - 1));
  293.   DELETE(rectStr, 1, where);
  294.  
  295.   tempRect.bottom := StrToNum(ParamPtr, rectStr);
  296.   strToRect := tempRect;
  297.  end;
  298.  
  299.  function HCWindowRect (paramPtr: XCMDPtr): rect;
  300. { the rect of HC's card window, in GLOBAL coordinates }
  301.   var
  302.    theResult: Handle;
  303.    rectStr: str255;
  304.    theLength: INTEGER;
  305.  begin
  306.   rectStr := 'the rect of card window';
  307.   theResult := EvalExpr(paramPtr, rectStr);
  308.   if (theResult <> nil) and (paramPtr^.result = noErr) then
  309.    ZeroToPas(paramPtr, theResult^, rectStr)
  310.   else
  311.    rectStr := '';
  312.   if (theResult <> nil) then
  313.    DisposHandle(theResult);
  314.   HCWindowRect := strToRect(paramPtr, rectStr);
  315.  end;
  316.  
  317.  function TheClickLoc (paramPtr: XCMDPtr): Point;
  318. { get the point at which the mouse was last clicked }
  319.   var
  320.    theResult: Handle;
  321.    ptStr: str255;
  322.    where: Integer;
  323.  begin
  324.   ptStr := 'the clickLoc';
  325.   theResult := EvalExpr(paramPtr, ptStr);{ where was the mouse clicked? }
  326.   if (theResult = nil) or (paramPtr^.result <> noErr) then
  327.    begin
  328.     theClickLoc.v := 0;
  329.     theClickLoc.h := 0;
  330.    end
  331.   else
  332.    begin
  333.     ZeroToPas(paramPtr, theResult^, ptStr);
  334.     where := POS(',', ptStr);
  335.     TheClickLoc.h := StrToNum(ParamPtr, COPY(ptStr, 1, where - 1));
  336.     DELETE(ptStr, 1, where);
  337.     TheClickLoc.v := StrToNum(ParamPtr, ptStr);
  338.    end;
  339.  
  340.   if (theResult <> nil) then
  341.    DisposHandle(theResult);     { free up the handle's memory! }
  342.  end;
  343.  
  344.  function GetGrayRgn: rgnhandle;
  345. { grab the region handle than represents the desktop }
  346.   var
  347.    tempRgn: rgnhandle;
  348.    deskRgnPtr: ^rgnhandle;
  349.  begin
  350.   deskRgnPtr := pointer($9EE);
  351.   tempRgn := deskRgnPtr^;
  352.   GetGrayRgn := tempRgn;
  353.  end;
  354.  
  355.  function GrayRgnBBox: rect;
  356. { get the rectangle that encloses the desktop }
  357.   var
  358.    grayRgn: rgnHandle;
  359.    tempRect: rect;
  360.  begin
  361.   SetRect(tempRect, 0, 0, 0, 0);{ make an empty rect }
  362.   grayRgn := GetGrayRgn;
  363.   if grayRgn <> nil then
  364.    GrayRgnBBox := grayRgn^^.rgnBBox
  365.   else
  366.    GrayRgnBBox := tempRect;
  367.  end;
  368.  
  369.  procedure DragRect (paramPtr: XCmdPtr);
  370.   var
  371.    itemRect, maxRect: Rect;
  372.    newX, newY: integer;
  373.    tempStr, tempY, tempX: Str255;
  374.    copyRtStr, syntaxStr: str255;
  375.    startPt: Point;
  376.    newPt: LongInt;
  377.    dragRgn, tempRgn: RgnHandle;
  378.    HCPort: GrafPtr;
  379.    deskPort: GrafPort;
  380.    err: OSErr;
  381.    doClipping: boolean;
  382.  begin
  383.   copyRtStr := 'v1.1, ┬⌐ 1989, 1990 Apple Computer, Inc. written by Eric Carlson';
  384.   syntaxStr := 'DragRect(objectRect, <ΓÇ£NOCLIPPINGΓÇ¥>';
  385.   if paramPtr^.paramCount < 1 then
  386.    begin
  387.     paramPtr^.returnValue := PasToZero(paramPtr, syntaxStr);
  388.     exit(DragRect);
  389.    end;
  390.  
  391.   if AskedForHelp(paramPtr, syntaxStr, copyRtStr) then
  392.    exit(DragRect);
  393.  
  394.   ZeroToPas(paramPtr, paramPtr^.params[1]^, tempStr);{ now get the rect of the outline to drag }
  395.   itemRect := StrToRect(paramPtr, tempStr);{ convert our string to a rect }
  396.   LocalToGlobal(itemRect.TopLeft);{ convert from HC's coords to global so we can make local to our new port later }
  397.   LocalToGlobal(itemRect.BotRight);
  398.  
  399. { now create a rect to which the dragging will be confined - note that it is initially in GLOBAL coords }
  400. { and must be converted to LOCAL coordinates when we open up a new port }
  401.   if paramPtr^.paramCount > 1 then
  402.    ZeroToPas(paramPtr, paramPtr^.params[2]^, tempStr);
  403.   if EqualString(tempStr, 'NOCLIPPING', false, false) then
  404.    doClipping := false
  405.   else
  406.    doClipping := true;
  407.  
  408.   startPt := TheClickLoc(paramPtr);{ start the dragging at the last position clicked }
  409.   LocalToGlobal(startPt);{ convert to global so we can make local to our new port later }
  410.  
  411.   GetPort(HCPort);{ remember HC's port so that we can restore it later }
  412.   OpenPort(@deskPort);{ create and init a new graf port }
  413.   err := MemError;{ see if it was successful }
  414.   if err <> noErr then
  415.    begin{ error, return no movement as we won't get the chance to drag anything }
  416.     paramPtr^.returnValue := PasToZero(ParamPtr, concat('0', ',', '0'));
  417.     exit(DragRect);
  418.    end;
  419.  
  420. { a newly opened port is set the the same size as the default monitor (IM I-163), thus any drawing will be limited to }
  421. {  this area.  expand the port and it's vis region to encompass the size of the desktop if ΓÇ£NOCLIPPINGΓÇ¥ was requested }
  422.   PortSize(maxRect.right - maxRect.left, maxRect.bottom - maxRect.top);{ first the port itself }
  423.   if not (doClipping) then
  424.    begin
  425.     maxRect := GrayRgnBBox;{ allow dragging anywhere on screen by using the smallest rect which describes }
  426. {  the desktop region as our max rect }
  427.     CopyRgn(GetGrayRgn, deskPort.visRgn);{ now the new port's visible region }
  428.    end
  429.   else
  430.    begin
  431.     maxRect := HCWindowRect(paramPtr);{ limit dragging to inside of the card window by using it's rectangle }
  432.     tempRgn := NewRgn;{ create a new region, empty so far }
  433.     RectRgn(tempRgn, maxRect);{ make it the size of the card window }
  434.     CopyRgn(tempRgn, deskPort.visRgn);{ and set the new port's visible region to it }
  435.     DisposeRgn(tempRgn);{ toss our allocated region! }
  436.    end;
  437.  
  438. { set up the rect of the item to be dragged }
  439.   GlobalToLocal(itemRect.TopLeft);{ convert from global coords to those of our new port }
  440.   GlobalToLocal(itemRect.BotRight);
  441.  
  442.   dragRgn := NewRgn;{ create a new region, empty so far }
  443.   RectRgn(dragRgn, itemRect);{ make it the size of the rect to be dragged }
  444.  
  445. { and the location to start the dragging }
  446.   GlobalToLocal(startPt);{ convert from global coords to those of our new port }
  447.  
  448. { and the size of the limiting rect }
  449.   with maxRect do{  convert to local coordinates and inset by 5 pixels on all sides }
  450.    begin
  451.     GlobalToLocal(TopLeft);
  452.     GlobalToLocal(BotRight);
  453.     top := top + 5;
  454.     left := left + 5;
  455.     right := right - 5;
  456.     bottom := bottom - 5;
  457.    end;
  458.  
  459.   newPt := DragGrayRgn(dragRgn, startPt, maxRect, maxRect, noConstraint, nil);
  460.  
  461. { both words of the resulting point = -32768 ($8000) if the mouse was released outside of the maxRect }
  462.   if newPt <> $80008000 then
  463.    begin
  464.     newX := LoWord(newPt);
  465.     newY := HiWord(newPt);
  466.    end
  467.   else
  468.    begin{ released 'out of bounds', return no movement }
  469.     newX := 0;
  470.     newY := 0;
  471.    end;
  472.  
  473.   DisposeRgn(dragRgn);{ toss our allocated region! }
  474.  
  475.   ClosePort(@deskPort);
  476.   SetPort(HCPort);{ make sure HC has its port back in its old shape }
  477.  
  478.   tempX := NumberToString(paramPtr, newX);{ convert the X to a string }
  479.   tempY := NumberToString(paramPtr, newY);{ and the Y value }
  480.   paramPtr^.returnValue := PasToZero(ParamPtr, concat(tempX, ',', tempY));
  481.  end;
  482.  
  483.  
  484.  procedure main (paramPtr: XCmdPtr);
  485.  begin
  486.   DragRect(paramPtr);
  487.  end;
  488. end.